import { useContext, useEffect, createContext } from "react";

var _contexts = new Map();

/**
 * 向缓存中添加 context 对象，采用弱引用的方式，防止对象不被释放
 *
 */
var _addContext = function(name, value){
	_contexts.set(name, value);
	// //先清除已经释放了的 Context 的设置
	// _clearWeakRef();
	// //如果 name 没有值，则不加入缓存
	// if(!name){
	// 	return;
	// }
	// let wr = new WeakRef(value);
	// _contexts.set(name, wr);
}

/**
 * 从缓存中获取 context 对象	
 */
var _getContext = function(name){
	return _contexts.get(name);
	// //先清除已经释放了的 Context 的设置
	// _clearWeakRef();
	// //获取 WeakRef 对象
	// const ref = _contexts.get(name);
	// if(ref === undefined){
	// 	return;
	// }
	// //从 WeakRef 对象取值
	// return ref.deref();
}

/**
 * 清除 _contexts 中 Context 已经被释放的 WeakRef 对象
 * 理论上是不需要执行此操作的，为以防万一，在每次 set 和 get 时都执行一篇此操作
 */
var _clearWeakRef = function(){

	//map 迭代器
	let iterator = _contexts.entries();
	//记录要移除的 name 值
	var names = [];
	while(true){
		let item = iterator.next();
		if(item && item.done == true){
			break;
		}

		if(item[1] !== undefined && item[1].deref() === undefined){
			names.push(item[0]);
		}
	}

	for(var n = 0; n<names.length;n++){
		_contexts.delete(names[n]);
	}
}
export function useCessContext(name){
	return useContext(_getContext(name));
}

/**
 * 创建 Context 对象，并且加入缓存，在组件 will unmount 时从缓存中移除
 */
export function createCessContext(name){
	const AppContext = createContext();

	useEffect(() => {
		return ()=>{
			//componentWillUnmount
			//当组件 unmount 时，从缓存中移除 Context 对象
			_contexts.delete(name);
		}
	}, []);

	_addContext(name, AppContext);

	return AppContext;
}